<script lang="ts" setup name="Layout">
import hotkeys from 'hotkeys-js'
import { useI18n } from 'vue-i18n'
import useSettingsStore from '@g/store/modules/settings'
import useMenuStore from '@g/store/modules/menu'
import useUserStore from '@g/store/modules/user'
import { ElMessage } from 'element-plus'
import IframeView from './components/views/iframe.vue'
import LinkView from './components/views/link.vue'
import Header from './components/Header/index.vue'
import MainSidebar from './components/MainSidebar/index.vue'
import SubSidebar from './components/SubSidebar/index.vue'
import Topbar from './components/Topbar/index.vue'
import Search from './components/Search/index.vue'
import AppSetting from './components/AppSetting/index.vue'
import HotkeysIntro from './components/HotkeysIntro/index.vue'
import Password from './components/Password/index.vue'
import useKeepAliveStore from '@/global/store/modules/keep-alive'

const routeInfo = useRoute()

const settingsStore = useSettingsStore()
const keepAliveStore = useKeepAliveStore()
const userStore = useUserStore()
const menuStore = useMenuStore()
const router = useRouter()
const isIframe = computed(() => !!routeInfo.meta.iframe)
const isLink = computed(() => !!routeInfo.meta.link)
const { t } = useI18n()
const pwdVisible = computed(() => userStore.pwdVisible)

useWatermark()

watch(() => settingsStore.settings.menu.subMenuCollapse, val => {
  if (settingsStore.mode === 'mobile') {
    if (!val)
      document.body.classList.add('ik_hidden')

    else
      document.body.classList.remove('ik_hidden')
  }
})

watch(() => routeInfo.path, () => {
  if (settingsStore.mode === 'mobile') {
    settingsStore.$patch(state => {
      state.settings.menu.subMenuCollapse = true
    })
  }
})

const toggleAnimation = computed(() => settingsStore.settings.mainPage.enableTransition ? (settingsStore.settings.mainPage.transitionMode || 'slide-right') : 'slide-right')
const changePassword = () => {
  userStore.pwdVisible = false
  ElMessage.info(t('app.logout'))
  userStore.logout().then(() => {
    router.push({
      name: 'login'
    })
  })
}

const mainPage = useMainPage()

onMounted(() => {
  hotkeys('f5', e => {
    if (settingsStore.settings.toolbar.enablePageReload) {
      e.preventDefault()
      mainPage.reload()
    }
  })
  hotkeys('alt+`', e => {
    if (settingsStore.settings.menu.enableHotkeys) {
      e.preventDefault()
      useMenu().switchTo(menuStore.actived + 1 < menuStore.allMenus.length ? menuStore.actived + 1 : 0)
    }
  })
  hotkeys('alt+up,alt+down', (e, handle) => {
    e.preventDefault()
    switch (handle.key) {
      case 'alt+up':
        mainPage.maximize(true)
        break
      case 'alt+down':
        mainPage.maximize(false)
        break
    }
  })
})
onUnmounted(() => {
  hotkeys.unbind('f5')
  hotkeys.unbind('alt+`')
  hotkeys.unbind('alt+up,alt+down')
})

const isOnlyHead = computed(() => settingsStore.settings.menu.menuMode === EMenuModel.ONLY_HEAD)
</script>

<template>
  <div class="layout">
    <div id="app-main" :class="{ 'main-page-maximize': settingsStore.mainPageMaximizeStatus }">
      <Header />
      <div class="wrapper">
        <div class="sidebar-container" :class="{ show: settingsStore.mode === 'mobile' && !settingsStore.settings.menu.subMenuCollapse }">
          <MainSidebar />
          <SubSidebar />
        </div>
        <div class="sidebar-mask" :class="{ show: settingsStore.mode === 'mobile' && !settingsStore.settings.menu.subMenuCollapse }" @click="settingsStore.toggleSidebarCollapse()"></div>
        <div
          class="main-container"
          :class="{ 'is-only-head': isOnlyHead }"
          :style="{ 'padding-bottom': routeInfo.meta.paddingBottom as any }"
        >
          <Topbar />
          <div class="main">
            <div v-show="settingsStore.mainPageMaximizeStatus" class="exit-main-page-maximize" @click="settingsStore.setMainPageMaximize()">
              <IkSvgIcon
                name="iksvg_guanbi"
                rotate="45"
                pop
                title="退出"
              />
            </div>
            <router-view v-slot="{ Component, route }">
              <transition
                :name="toggleAnimation"
                mode="out-in"
                appear
              >
                <keep-alive :include="keepAliveStore.list">
                  <div :key="route.fullPath" class="flex flex-col flex-1">
                    <component :is="Component" v-show="!(isIframe || isLink)" :key="route.fullPath" />
                  </div>
                </keep-alive>
              </transition>
            </router-view>
            <IframeView v-show="isIframe && !isLink" />
            <LinkView v-if="isLink" />
          </div>
          <IkCopyright />
        </div>
      </div>
      <el-backtop :right="20" :bottom="20" title="回到顶部" />
    </div>
    <Search />
    <AppSetting />
    <HotkeysIntro />
    <Password :visible="pwdVisible" @success="changePassword" />
  </div>
</template>

<style lang="scss" scoped>
[data-app-width-mode="adaption"] {
  #app-main {
    width: 100%;
  }
}

[data-app-width-mode="adaption-min-width"] {
  #app-main {
    width: max(var(--ik-app-width), 100%);
  }
}

[data-app-width-mode="center"] {
  #app-main {
    width: var(--ik-app-width);
  }
}

[data-app-width-mode="center-max-width"] {
  #app-main {
    width: min(var(--ik-app-width), 100%);
  }
}

[data-mode="mobile"] {
  #app-main {
    width: 100%;
  }

  .sidebar-container {
    transform: translateX(calc((var(--ik-main-sidebar-width) + var(--ik-sub-sidebar-width)) * -1));

    &.show {
      transform: translateX(0);
    }
  }

  .main-container {
    margin-left: 0 !important;
  }

  &[data-menu-mode="single"] {
    .sidebar-container {
      transform: translateX(calc(var(--ik-sub-sidebar-width) * -1));

      &.show {
        transform: translateX(0);
      }
    }
  }
}
</style>

<style lang="scss" scoped>
.layout {
  height: 100%;
}

#app-main {
  height: 100%;
  margin: 0 auto;
  transition: var(--el-transition-all);

  // 当前标签页全屏
  &.main-page-maximize {
    --ik-margin-top-with-bread: 24px;

    header,
    .sidebar-container {
      display: none;
    }

    .wrapper {
      padding-top: 0;

      .main-container {
        margin-left: 0;

        .topbar-container {
          display: none;
        }

        .main {
          margin: 0;
        }
      }
    }

    :deep([data-fixed-calc-width]) {
      width: 100%;
      transform: translateX(-50%);
    }
  }
}

.wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  transition: padding-top 0.3s;

  .sidebar-container {
    position: fixed;
    z-index: 1010;
    top: 0;
    bottom: 0;
    display: flex;
    width: calc(var(--ik-main-sidebar-actual-width) + var(--ik-sub-sidebar-actual-width));
    box-shadow: -1px 0 0 0 var(--ik-border-color);
    transition: transform 0.3s, var(--el-transition-box-shadow), top 0.3s;
  }

  .sidebar-mask {
    position: fixed;
    z-index: 1000;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: radial-gradient(transparent 1px, rgb(0 0 0 / 30%) 1px);
    background-size: 4px 4px;
    backdrop-filter: saturate(50%) blur(4px);
    transition: all 0.2s;
    opacity: 0;
    visibility: hidden;

    &.show {
      opacity: 1;
      visibility: visible;
    }
  }

  .main-sidebar-container:not(.main-sidebar-leave-active) + .sub-sidebar-container {
    left: var(--ik-main-sidebar-width);
  }

  .main-container {
    display: flex;
    flex-direction: column;
    min-height: 100%;
    margin-left: calc(var(--ik-main-sidebar-actual-width) + var(--ik-sub-sidebar-actual-width));
    background-color: var(--ik-main-bg);
    box-shadow: -1px 0 0 0 var(--ik-border-color), 1px 0 0 0 var(--ik-border-color);
    transition: margin-left 0.3s, background-color 0.3s, var(--el-transition-box-shadow);
    --ik-toolbar-height: 64px;

     &.is-only-head{
        --ik-toolbar-height: 0px;

        .main {
           .topbar-container.has-tabbar.has-toolbar.has-breadcrumb + .main {
              margin: calc(var(--ik-tabbar-height) + var(--ik-toolbar-height) + var(--ik-breamcrumb-height) + 47px) 0 0;
            }

        }
      }

    .main {
      height: 100%;
      flex: auto;
      position: relative;
      overflow: auto;
      transition: 0.3s;
      overflow-x: hidden;
      display: flex;
      flex-direction: column;

      .exit-main-page-maximize {
        position: fixed;
        z-index: 1000;
        right: -34px;
        transform: rotateZ(-45deg);
        top: -31px;
        width: 70px;
        height: 70px;
        border-radius: 50%;
        cursor: pointer;
        background-color: var(--el-overlay-color-lighter);
        color: #eee;
        transition: background-color 0.3s, var(--el-transition-color);

        &:hover {
          background-color: var(--el-overlay-color-light);
          color: #fff;
        }

        :deep(.ik-iksvg_guanbi) {
          position: absolute;
          bottom: 20px;
          left: 0;
        }
      }
    }

    .topbar-container.has-tabbar + .main {
      margin: var(--ik-tabbar-height) 0 0;
    }

    .topbar-container.has-toolbar + .main {
      margin: var(--ik-toolbar-height) 0 0;
    }

    .topbar-container.has-tabbar.has-toolbar + .main {
      margin: calc(var(--ik-tabbar-height) + var(--ik-toolbar-height)) 0 0;
    }

    .topbar-container.has-breadcrumb + .main {
      margin: var(--ik-breamcrumb-height) 0 0;
    }

     .topbar-container.has-tabbar.has-breadcrumb + .main {
      margin: calc(var(--ik-tabbar-height) + var(--ik-breamcrumb-height)) 0 0;
    }

     .topbar-container.has-toolbar.has-breadcrumb + .main {
      margin: calc(var(--ik-toolbar-height) + var(--ik-breamcrumb-height) + 22px) 0 0;
    }

    .topbar-container.has-tabbar.has-toolbar.has-breadcrumb + .main {
      margin: calc(var(--ik-tabbar-height) + var(--ik-toolbar-height) + var(--ik-breamcrumb-height) + 22px) 0 0 0;
    }

    .topbar-container.has-tabbar.has-toolbar.has-breadcrumb.is-only-head + .main {
      margin: calc(var(--ik-tabbar-height) + var(--ik-toolbar-height) + var(--ik-breamcrumb-height) + 24px) 0 0 0;
    }
  }
}

header:not(.header-leave-active) + .wrapper {
  padding-top: var(--ik-header-height);

  .sidebar-container {
    top: var(--ik-header-height);

    :deep(.sidebar-logo) {
      display: none;
    }

    :deep(.el-menu) {
      padding-top: 0;
    }
  }

  .main-container {
    .topbar-container {
      //  + var(--base-m)
      top: calc(var(--ik-header-height));

      :deep(.tools) {
        display: none;
      }
    }
  }
}

// 主内容区动画
.fade-enter-active,
.slide-left-enter-active,
.slide-right-enter-active,
.slide-top-enter-active,
.slide-bottom-enter-active {
  transition: 0.2s;
}

.fade-leave-active,
.slide-left-leave-active,
.slide-right-leave-active,
.slide-top-leave-active,
.slide-bottom-leave-active {
  transition: 0.15s;
}

.fade-enter-from {
  opacity: 0;
}

.fade-leave-to {
  opacity: 0;
}

.slide-left-enter-from {
  opacity: 0;
  margin-left: 20px;
}

.slide-left-leave-to {
  opacity: 0;
  margin-left: -20px;
}

.slide-right-enter-from {
  opacity: 0;
  margin-left: -20px;
}

.slide-right-leave-to {
  opacity: 0;
  margin-left: 20px;
}

.slide-top-enter-from {
  opacity: 0;
  margin-top: 20px;
}

.slide-top-leave-to {
  opacity: 0;
  margin-top: -20px;
}

.slide-bottom-enter-from {
  opacity: 0;
  margin-top: -20px;
}

.slide-bottom-leave-to {
  opacity: 0;
  margin-top: 20px;
}
</style>
